import Dep from "./Dep";

var uid = 0
export default class Watcher{
  constructor(target, expression, callback){
    this.uid = uid ++;
    this.target = target;
    this.getter = parsePath(expression)
    this.callback = callback
    this.value = this.get()
  }
  update(){
    this.run()
  }
  get(){
    Dep.target = this
    const obj = this.target
    try{
      this.getter(obj)
    }finally{
      this.getter= null
    }
    
  }
  run(){
    this.getAndInvoke(this.callback);
  }
  getAndInvoke(cb){
    const value = this.get();
    if(value != this.value ||typeof value == 'object'){
      const oldValue = this.value;
      this.value =value
      cb.call(this.target,value,oldValue)
    }
  }
}
function parsePath(exp){
  var segments =exp.split('.')
  return obj=>{
    for(let i = 0,l=segments.length;i<l;i++){
      obj = obj[segments[i]]
    }
    return obj
  }
}